/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.unisc.pdaapp.webservice.client;

import org.kobjects.base64.Base64;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

/**
 *
 * @author guilherme
 */
public class WSHandler implements br.unisc.pdaapp.meta.ws.IMoodleMobileWS
{

//    private static String HOST = "10.160.0.27";
//    private static String HOST = "10.160.3.84";
    private static String HOST = "10.1.1.3";
//    private static String HOST = "192.168.0.161";

    private String url = "http://" + HOST + ":8080/axis2/services/MoodleMobileWS";

    public static final String NAMESPACE = "http://webservice.server.pdaapp.unisc.br";

    private static final String SOAP_ACTION = "";

    public WSHandler() throws Exception
    {
    }

    /**
     * Realiza o login utilizando a API do KSoap.
     * @param userNameValue Nome do usuário.
     * @param passwordValue Senha do usuário.
     * @return Um inteiro representando se o login foi executado com sucesso(1 ou 2) ou não(0).
     * @throws java.lang.Exception
     */
    private int doLoginByKsoapJ2SE(String userNameValue, String passwordValue) throws Exception
    {
        SoapSerializationEnvelope envelop = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        SoapObject client = new SoapObject(NAMESPACE, "doLogin");

        PropertyInfo user = new PropertyInfo();
        user.name = "userName";
        user.namespace = NAMESPACE;
        user.type = PropertyInfo.STRING_CLASS;

        PropertyInfo passwd = new PropertyInfo();
        passwd.name = "passwd";
        passwd.namespace = NAMESPACE;
        passwd.type = PropertyInfo.STRING_CLASS;

        client.addProperty(user, userNameValue);
        client.addProperty(passwd, passwordValue);

        envelop.setOutputSoapObject(client);

        HttpTransportSE transport = new HttpTransportSE("http://" + HOST + ":8080/axis2/services/MoodleMobileWS");
        //transport.debug = true;

        transport.call(SOAP_ACTION, envelop);

        Object result = envelop.getResponse();

        return Integer.parseInt(result.toString());
    }

    private int updateByKsoapJ2SE(String[] paramKey, String[] paramValue, String methodToCall) throws Exception
    {
        SoapSerializationEnvelope envelop = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        SoapObject client = new SoapObject(NAMESPACE, methodToCall);
        PropertyInfo user = null;

        for (int x = 0; x < paramKey.length; x++)
        {
            user = new PropertyInfo();
            user.name = paramKey[x];
            user.namespace = NAMESPACE;
            user.type = PropertyInfo.STRING_CLASS;

            client.addProperty(user, "" + paramValue[x]);
        }

        envelop.setOutputSoapObject(client);

        HttpTransportSE transport = new HttpTransportSE("http://" + HOST + ":8080/axis2/services/MoodleMobileWS");
        //transport.debug = true;

        transport.call(SOAP_ACTION, envelop);

        Object result = envelop.getResponse();

        return Integer.parseInt(result.toString());
    }

    private void addClassMappings(SoapSerializationEnvelope envelope)
    {
        createWrappingResultTemplate(envelope);
        new GetCoursesResult().register(envelope, NAMESPACE, "GetCoursesResult");
    }

    private void createWrappingResultTemplate(SoapSerializationEnvelope envelope)
    {
        // tell ksoap what type of attribute the Resulting Object has.
        PropertyInfo info = new PropertyInfo();
        info.name = "GetCoursesResult";
        info.type = new GetCoursesResult().getClass();

        // Demonstration of using a template to describe what the result will
        // look like. KSOAP will actually clone this object and fill it with
        // the resulting information.
        // You could use a real object here as well, your choice.
        // However, If you fail to tell ksoap what to
        // expect however it will not try to map any
        // contained objects to their classes.

        SoapObject template = new SoapObject(NAMESPACE, "GetCoursesResponse");
        template.addProperty(info, "not important what this is");

        envelope.addTemplate(template);
    }

    private byte[] getByteArrayByKsoapJ2SE(String[] paramKey, String[] paramValue, String methodToCall) throws Exception
    {
        SoapSerializationEnvelope envelop = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        SoapObject client = new SoapObject(NAMESPACE, methodToCall);
        PropertyInfo user = null;

        for (int x = 0; x < paramKey.length; x++)
        {
            user = new PropertyInfo();
            user.name = paramKey[x];
            user.namespace = NAMESPACE;
            user.type = PropertyInfo.STRING_CLASS;

            client.addProperty(user, "" + paramValue[x]);
        }

        envelop.setOutputSoapObject(client);

        //addClassMappings(envelop);

        HttpTransportSE transport = new HttpTransportSE("http://" + HOST + ":8080/axis2/services/MoodleMobileWS");
        //transport.debug = true;

        transport.call(SOAP_ACTION, envelop);

        SoapPrimitive result = (SoapPrimitive) envelop.getResponse();

        return Base64.decode(result.toString());
    }

    public int doLogin(String userName, String passwd)
    {
        try
        {
            return doLoginByKsoapJ2SE(userName, passwd);
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return -1; //EXCEPTION in LOGIN
    }

    /**
     * Retorna os cursos do nome de usuário passado por parametro.
     *
     * @param userName Nome de usuário de login do moodle
     * @return
     */
    public byte[] getCourses(String userName)
    {
        try
        {
            return getByteArrayByKsoapJ2SE(new String[]
                    {
                        "userName"
                    }, new String[]
                    {
                        userName
                    }, "getCourses");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return null;
    }

    /**
     * Retorna as aulas do seguinte curso passado por parametro.
     *
     * @param courseID È o courseID na base de dados do moodle.
     * @return Um array de bytes que é um xml com as respectivas aulas do curso.
     */
    public byte[] getClasses(int courseID)
    {
        try
        {
            return getByteArrayByKsoapJ2SE(new String[]
                    {
                        "courseID"
                    }, new String[]
                    {
                        "" + courseID
                    }, "getClasses");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return null;
    }

    public byte[] getMessages(String userName)
    {
        try
        {
            return getByteArrayByKsoapJ2SE(new String[]
                    {
                        "userName"
                    }, new String[]
                    {
                        userName
                    }, "getMessages");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return null;
    }

    public byte[] getUsersByCourse(int courseID)
    {
        try
        {
            return getByteArrayByKsoapJ2SE(new String[]
                    {
                        "courseID"
                    }, new String[]
                    {
                        String.valueOf(courseID)
                    }, "getUsersByCourse");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return null;
    }

    /**
     * Sends a message.
     *
     * @param fromUser The user is going to send the message.
     * @param targetUsers The target users to recieve the message. It must be separeted by ";".
     * @param message The message.
     * @return
     */
    public int sendMessage(String fromUser, String targetUsers, String message)
    {
        try
        {
            String[] keys = new String[]
            {
                "fromUser", "targetUsers", "message"
            };
            String[] values = new String[]
            {
                fromUser, targetUsers, message
            };

            return updateByKsoapJ2SE(keys, values, "sendMessage");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return -1;
    }

    public int deleteMessage(int messageID)
    {
        try
        {
            return updateByKsoapJ2SE(new String[]
                    {
                        "messageID"
                    }, new String[]
                    {
                        "" + messageID
                    }, "deleteMessage");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return -1;
    }

    public byte[] getMaterial(int courseID, int courseSectionID)
    {
        try
        {
            String[] keys = new String[]
            {
                "courseID", "courseSectionID"
            };
            String[] values = new String[]
            {
                "" + courseID, "" + courseSectionID
            };

            return getByteArrayByKsoapJ2SE(keys, values, "getMaterial");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return null;
    }

    /**
     * Aualiza a visibilidade da seguinte aula passada por parametro.
     *
     * @param classID É o ID da aula de um curso no moodle.
     * @param visible Boolean que indica se a classe será vísivel ou não.
     * @return Um inteiro que representa se a query foi executada com sucesso(1) ou não(0).
     */
    public int updateClassVisibility(int courseID, int sectionID, boolean visible)
    {
        try
        {
            String[] keys = new String[]
            {
                "courseID", "courseSectionID", "visible"
            };
            String[] values = new String[]
            {
                String.valueOf(courseID), String.valueOf(sectionID), String.valueOf(visible)
            };

            return updateByKsoapJ2SE(keys, values, "updateClassVisibility");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return -1;
    }

    public int updateMaterialVisibility(int instance, int courseID, int courseSectionID, int courseModuleID, boolean visible)
    {
        try
        {
            String[] keys = new String[]
            {
                "instance", "courseID", "courseSectionID", "courseModuleID", "visible"
            };
            String[] values = new String[]
            {
                String.valueOf(instance), String.valueOf(courseID), String.valueOf(courseSectionID), String.valueOf(courseModuleID), String.valueOf(visible)
            };

            return updateByKsoapJ2SE(keys, values, "updateMaterialVisibility");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return -1;
    }

    public byte[] downloadMaterial(int courseID, String fileName)
    {
        try
        {
            String[] keys = new String[]
            {
                "courseID", "fileName"
            };
            String[] values = new String[]
            {
                "" + courseID, fileName
            };

            return getByteArrayByKsoapJ2SE(keys, values, "downloadMaterial");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return null;
    }

    public int uploadMaterial(int courseID, int courseSectionID, String file, String fileName)
    {
        try
        {
            SoapSerializationEnvelope envelop = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            SoapObject client = new SoapObject(NAMESPACE, "uploadMaterial");

            PropertyInfo courseIDProp = new PropertyInfo();
            courseIDProp.name = "courseID";
            courseIDProp.namespace = NAMESPACE;
            courseIDProp.type = PropertyInfo.STRING_CLASS;
            client.addProperty(courseIDProp, "" + courseID);

            PropertyInfo courseSectionIDProp = new PropertyInfo();
            courseSectionIDProp.name = "courseSectionID";
            courseSectionIDProp.namespace = NAMESPACE;
            courseSectionIDProp.type = PropertyInfo.STRING_CLASS;
            client.addProperty(courseSectionIDProp, "" + courseSectionID);

            PropertyInfo fileProp = new PropertyInfo();
            fileProp.name = "file";
            fileProp.namespace = NAMESPACE;
            fileProp.type = PropertyInfo.STRING_CLASS;
            client.addProperty(fileProp, new SoapPrimitive(SoapEnvelope.ENC, "base64", file));

            PropertyInfo fileNameProp = new PropertyInfo();
            fileNameProp.name = "fileName";
            fileNameProp.namespace = NAMESPACE;
            fileNameProp.type = PropertyInfo.STRING_CLASS;
            client.addProperty(fileNameProp, fileName);

            envelop.setOutputSoapObject(client);

            HttpTransportSE transport = new HttpTransportSE("http://" + HOST + ":8080/axis2/services/MoodleMobileWS");
            transport.call(SOAP_ACTION, envelop);

            Object result = envelop.getResponse();
            return Integer.parseInt(result.toString());
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return -1;
    }
}
